package services

import (
	"errors"
	"fmt"
	"hft/Database/admin"
	"hft/Http/Models/dao"
	"hft/Http/Models/request"
	"hft/Http/Services/base"
	utils "hft/Http/Utils"
	"hft/e"
	"hft/global"
	"hft/tools"
	"regexp"

	"gorm.io/gorm"
)

type User struct{}

func (*User) CreateUser(data *admin.User, clue *admin.Clue) (err error) {

	err = global.OC_DB.Transaction(func(tx *gorm.DB) error {
		tx.Create(&data)
		tx.Model(&data).Association("ClueList").Append(clue)

		return nil
	})

	return err
}

func (*User) UpdateUser(data *admin.User, clue *admin.Clue) (err error) {

	err = global.OC_DB.Transaction(func(tx *gorm.DB) error {

		err = tx.Model(&admin.User{}).Where("id = ?", data.ID).Updates(&data).Error

		if err != nil {
			return errors.New("未知错误500")
		}

		tx.Model(&data).Association("ClueList").Append(clue)

		return nil
	})

	return err
}

func (*User) GetUserList(paginate *request.SearchCluePage, claims tools.BaseClaims) (data *utils.Page, err error) {

	account, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return nil, err
	}
	var regionLink string
	var region *admin.Region
	if paginate.Region != 0 {
		global.OC_DB.First(&region, paginate.Region)
		regionLink = fmt.Sprintf("%v%v,%%", region.Link, region.ID)
	} else {
		regionLink = fmt.Sprintf("%v%%", account.RegionLink)
	}

	var newList []*admin.User
	var accountLink = fmt.Sprintf("%v%v,", account.AccountLink, account.ID)
	global.OC_DB.Model(&admin.Clue{}).Scopes(dao.ClueDao.SearchUser(paginate, fmt.Sprintf("%v%%", accountLink), fmt.Sprintf("%v%%", regionLink), global.OC_DB)).Find(&newList).Scopes(dao.GetCount(global.OC_DB)).Count(&paginate.Total)

	paginate.Data = newList

	return &paginate.Page, nil
}

func (*User) GetUserInfo(id int, claims tools.BaseClaims) (data *admin.User, err error) {

	var account *admin.Account

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).Preload("Role").First(&account).Error

	var user *admin.User

	global.OC_DB.Preload("ClueList", func(db *gorm.DB) *gorm.DB {
		return db.Preload("PhoneRecord").Order("create_time desc")
	}).Preload("RemarkList").First(&user, id)

	return user, nil
}

// 屏蔽电话
func (*User) ShieldPhone(id int, claims tools.BaseClaims, shield bool) (err error) {
	account, err := base.FindAccount(claims, global.OC_DB)
	var user *admin.User
	if err = global.OC_DB.Where("id = ?", id).First(&user).Error; err != nil {
		return errors.New(e.UserNotFound)
	}
	if match, _ := regexp.MatchString(fmt.Sprintf("^%v%v,", account.AccountLink, account.ID), user.AccountLink); !match {
		return errors.New(e.NoRightToOpera)
	}
	if res := global.OC_DB.Model(&user).Where("id = ?", user.ID).Update("is_shield", shield); res.RowsAffected == 0 || res.Error != nil {
		return errors.New(e.ErrorInfo)
	}
	return nil
}

var UserService = new(User)
